<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />

    <script>

// https://es6.ruanyifeng.com/#docs/proxy

    var handler = {
    get: function(target, name) {
        if (name === 'prototype') {
        return Object.prototype;
        }
        return 'Hello, ' + name;
    },

    apply: function(target, thisBinding, args) {
        return args[0];
    },

    construct: function(target, args) {
        return {value: args[1]};
    }
    };

    var fproxy = new Proxy(function(x, y) {
    return x + y;
    }, handler);

    fproxy(1, 2) // 1
    fp=new fproxy(1, 2); // {value: 2}
    fproxy.prototype === Object.prototype // true
    fproxy.foo === "Hello, foo" // true


// var handler = {
//   deleteProperty (target, key) {
//     invariant(key, 'delete');
//     delete target[key];
//     return true;
//   }
// };
// function invariant (key, action) {
//   if (key[0] === '_') {
//     throw new Error(`Invalid attempt to ${action} private "${key}" property`);
//   }
// }

// var target = { _prop: 'foo' ,prop:"sex"};
// var proxy = new Proxy(target, handler);
// delete proxy.prop
// delete proxy._prop

// const p = new Proxy(function (x) {
//     console.log(x*x);
// }, {
//   construct: function(target, args) {
//     console.log('called: ' + args.join(', '));
//     return target;
//   }
// });

// let p1=new p(3);
// p1(11);

// let stu1 = {name: '张三', score: 59};
// // let stu2 = {name: '李四', score: 99};
// let stu2 = {};
// let handler = {
//   has(target, prop) {
//     if (prop === 'score' && target[prop] < 60) {
//       console.log(`${target.name} 不及格`);
//       return false;
//     }
//     return prop in target;
//   }
// }
// Object.setPrototypeOf(stu2,stu1);
// // let oproxy1 = new Proxy(stu1, handler);
// let oproxy2 = new Proxy(stu2, handler);

// // 'score' in oproxy1
// // 张三 不及格
// // false

// console.log('score' in oproxy2);
// // true


// function aa(x,y){

//     alert(this); // this 分别是undefined，student ,teacher
//     console.log(...arguments) //arguments 代表实际传递的参数。
// }

// aa(1,2);

// var student={name:"student"};
// aa.call(student,1,2)

// var teacher={name:"teacher"};
// aa.apply(teacher,1,2)
    // let obj={};
    // Object.defineProperties(obj,{"name":{writable:true,value:"szq",enumerable:true}})

    // const handler={
    //     set(target ,prop,value,receiver){
    //         // alert(prop);
    //         target[prop]=value;
    //         return true;
    //     }
    // }
    // let myproxy=new Proxy(obj,handler);
    // myproxy.name="szq222";
    // myproxy.age=11;
    // alert(myproxy.age);

// const handler = {
//   set: function(obj, prop, value, receiver) {
//     obj[prop] = receiver;
//     return true;
//   }
// };
// const proxy = new Proxy({}, handler);
// const myObj = {};
// myObj.name="aaa";
// Object.setPrototypeOf(myObj, proxy);

// myObj.foo = 'bar';
// console.log( myObj === myObj.foo) // true

// let myhandler={
//     set(target,prop,value,receiver){
//         if (prop==="age"){

//             if (!Number.isInteger(value)){
//                     // alert("not integer");
//                     return;
//             }
//             if (value>200){
//                 // alert("max is 200!");
//                 return;
//             }
//             target.age=value;
//              return true;
//         }

//     },
//     get(target ,prop,receiver){
//         return target.age;
//     }
// };

// let myproxy=new Proxy({},myhandler);
//     myproxy.age=100;
//     console.log(myproxy.age);
//     myproxy.age=200;
//     console.log(myproxy.age);
//     myproxy.age="abc";
//     console.log(myproxy.age);
//     myproxy.age="300";
//     console.log(myproxy.age);


// TypeError: Invariant check failed

        // const dom = new Proxy({}, {
        //     get(target, property) {
        //         return function (attrs = {}, ...children) {
        //             const el = document.createElement(property);
        //             for (let prop of Object.keys(attrs)) {
        //                 el.setAttribute(prop, attrs[prop]);
        //             }
        //             for (let child of children) {
        //                 if (typeof child === 'string') {
        //                     child = document.createTextNode(child);
        //                 }
        //                 el.appendChild(child);
        //             }
        //             return el;
        //         }
        //     }
        // });
    
        // const el = dom.div({},
        //     'Hello, my name is ',
        //     dom.a({ href: '//example.com' }, 'Mark'),
        //     '. I like:',
        //     dom.ul({},
        //         dom.li({}, 'The web'),
        //         dom.li({}, 'Food'),
        //         dom.li({}, '…actually that\'s it')
        //     )
        // );        
    
        // var pipe = function (value) {
        //     var funcStack = [];
        //     var oproxy = new Proxy({}, {
        //         get: function (pipeObject, fnName) {
        //             if (fnName === 'get') {
        //                 return funcStack.reduce(function (val, fn) {
        //                     return fn(val);
        //                 }, value);
        //             }
        //             if (fnName == "a") {
        //                 funcStack.push(window["double"]);
        //             } else {
        //                 funcStack.push(window[fnName]);
        //             }
    
        //             return oproxy;
        //         }
        //     });
    
        //     return oproxy; // 代理 空的对象 {} -》代理器加了一个拦截器 （对空对象属性的拦截器）
        // }
    
        // var double = n => n * 2; //3-> 3*2 =6
        // var pow = n => n * n;// 6->6*6=36
        // var reverseInt = n => n.toString().split("").reverse().join("") | 0;// 63
    
        // console.log(pipe(3).a.pow.reverseInt.get); // 63
    
        // console.log(obj.foo);// "GET foo"
        // console.log(obj.abc);// "GET abc"
    
        // var handler = {
        //     get: function (target, name) {
        //         if (name === 'prototype') {
        //             return Object.prototype;
        //         }
        //         return 'Hello, ' + name;
        //     },
    
        //     apply: function (target, thisBinding, args) {
        //         return args[0];
        //     },
    
        //     construct: function (target, args) {
        //         return { value: args[1] };
        //     },
        //     ownKeys(target) {
        //         return ["a", "b", "c"];
        //         // return { bb: "1", cc: "2", dd: "3", ee: "4" };
        //     }
        // };
    
        // var fproxy = new Proxy({ "a": "11", "b": "22", "c": "33", "d": "44", [Symbol("e")]: "55" }, handler);
    
        // let keys = Reflect.ownKeys(fproxy);
        // console.log(keys);
        // keys.forEach((x) => { console.log(x) });
        // for (let item in keys) { console.log(keys[item]); };
        // for (let item of keys) { console.log(item); };
    
    
        // fproxy(1, 2) // 1
        // new fproxy(1, 2) // {value: 2}
        // fproxy.prototype === Object.prototype // true
        // fproxy.foo === "Hello, foo" // true
    
    
    
    
    
        // var proxy = new Proxy({}, {
        //     get: function (target, propKey, receiver) {
        //         return Reflect.get(target, propKey, receiver);
        //     },
        //     set: function (target, propKey, value, receiver) {
        //         value = 36;
        //         return Reflect.set(target, propKey, value, receiver);
        //     }
        // });
    
        // proxy.time = 50;
        // console.log(proxy.time);
    
        // // const  a=(x)=>{
        // //     console.log(x);
        // // }
        // const a = function (x) {
        //     console.log(x);
        // }
    
    //     var obj = new Proxy({}, {
    //         get: function (target, propKey, receiver) {
    //             console.log(`getting ${propKey}!`);
    //             return Reflect.get(target, propKey, receiver);
    //         },
    //         set: function (target, propKey, value, receiver) {
    //             console.log(`setting ${propKey}!`);
    //             return Reflect.set(target, propKey, value, receiver);
    //         }
    //     });
    
    //     obj.count = 1
    //     //  setting count!
    //     ++obj.count
    // //  getting count!
    // //  setting count!
    // //  2
    </script>
</head>

<body>
<div id="div1">

</div>
<script>
    // document.getElementById("div1").appendChild(el);
</script>
</body>

</html>